There are two reasons one might want to use inheritance: to share code, or to express your interface compliance. Ie: given a class 'B' ('B' stands for 'base class', which is called 'superclass' in Smalltalkese), a class 'D' which is derived from B is expressed this way:
class B { /*...*/ };
class D : public B { /*...*/ };
This says two distinct things: (1) the bits(data structure) + code(algorithms) are inherited from B, and (2) 'D's public interface is 'conformal' to 'B's (anything you can do to a B, you can also do to a D, plus perhaps some other things that only D's can do; ie: a D is-a-kind-of-a B).
In C++, one can use inheritance to mean:
--> #2(is-a) alone (ex:you intend to override most/all inherited code)
--> both #2(is-a) and #1(code-sharing)
but one should never Never use the above form of inheritance to mean
--> #1(code-sharing) alone (ex: D really *isn't* a B, but...)
This is a major difference with Smalltalk, where there is only one form of inheritance (C++ provides 'private' inheritance to mean 'share the code but don't conform to the interface'). The Smalltalk language proper (as opposed to coding practice) allows you to have the *effect* of 'hiding' an inherited method by providing an override that calls the 'does not understand' method. Furthermore Smalltalk allows a conceptual 'is-a' relationship to exist *apart* from the subclassing hierarchy (subtypes don't have to be subclasses; ex: you can make something that 'is-a Stack' yet doesn't inherit from 'Stack').
In contrast, C++ is more restrictive about inheritance: there's no way to make a 'conceptual is-a' relationship without using inheritance (the C++ work-around is to separate interface from implementation via ABCs). The C++ compiler exploits the added semantic information associated with public inheritance to provide static typing.